package server;

import java.io.*;

public class WebAppClassLoader extends  ClassLoader{

    private String classpath;

    public WebAppClassLoader(String classpath)
    {
        this.classpath = classpath;
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        Class<?> clazz = findLoadedClass(name);
        try{
            if(clazz == null) clazz = findClass(name);
        }catch (ClassNotFoundException e){
            // ClassNotFoundException thrown if class not found
            // from the non-null parent class loader
        }

        if(clazz == null && getParent() != null){
            clazz = getParent().loadClass(name);
        }

        if(resolve){
            resolveClass(clazz);
        }
        return clazz;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        try
        {
            byte[] classDate = getClassBinaryData(name);
            if (classDate == null)
            {

            }
            else
            { // defineClass方法将字节码转化为类
                return defineClass(name, classDate, 0, classDate.length);
            }
        }
        catch (IOException e)
        {
            throw new ClassNotFoundException();
        }
        return super.findClass(name);
    }



    private byte[] getClassBinaryData(String className) throws IOException
    {
        InputStream in = null;
        ByteArrayOutputStream out = null;
        String path = classpath + File.separatorChar + className.replace('.', File.separatorChar) + ".class";
        try
        {
            in = new FileInputStream(path);
            out = new ByteArrayOutputStream();
            byte[] buffer = new byte[2048];
            int len = 0;
            while ((len = in.read(buffer)) != -1)
            {
                out.write(buffer, 0, len);
            }
            return out.toByteArray();
        }
        catch (FileNotFoundException e)
        {
            throw new IOException();
        }
        finally
        {
            if(in != null) {
                in.close();
                out.close();
            }

        }
    }
}
